﻿using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using StockholmsStad.Data.Entity;
using StockholmsStad.Runtime.Serialization.DataContract.Enums;
using StockholmsStad.Utilities;
using Ceremony=StockholmsStad.Runtime.Serialization.DataContract.Ceremony;
using Couple=StockholmsStad.Runtime.Serialization.DataContract.Couple;
using System;

namespace StockholmsStad.Data.ContractFactory
{
    /// <summary>
    /// Konvertering befintligt dataobjekt till kontraktsobjekt
    /// </summary>
    internal class TicketFactory : FactoryAgent
    {
        #region Implementation of IConvertFactory

        public Ticket CreateEntityObject(Runtime.Serialization.DataContract.Ticket ticket, int ceremonyId)
        {
            var entityTicket = new Ticket
                                   {
                                       CeremonyId = ceremonyId
                                   };

            if (ticket.Couple.CoupleId.HasValue)
                entityTicket.CoupleId = ticket.Couple.CoupleId.Value;

            return entityTicket;
        }

        public Runtime.Serialization.DataContract.Ticket CreateContractObject(Ticket ticket, Ceremony ceremony)
        {
            Couple couple = new CoupleFactory().CreateContractObject(ticket.Couple);

            return new Runtime.Serialization.DataContract.Ticket
                       {
                           TicketId = ticket.TicketId,
                           Ceremony = ceremony,
                           Couple = couple,
                           Status = ticket.TicketStatus.Name,
                       };
        }

        public Runtime.Serialization.DataContract.CouplesSummaryItem CreateCouplesObject(FindTicketsResult ticketsResult)
        {
            var couplesItem = new Runtime.Serialization.DataContract.CouplesSummaryItem
            {
                Person1FirstName = ticketsResult.Person1FirstNames,
                Person1LastName = ticketsResult.Person1LastName,
                Person1Birthday = ticketsResult.Person1PersonalNumber,
                Person2FirstName = ticketsResult.Person2FirstNames,
                Person2LastName = ticketsResult.Person2LastName,
                Person2Birthday = ticketsResult.Person2PersonalNumber,
                ImpedimentDocIssuedDate = ticketsResult.ImpedimentDocIssuedDate,
                Note = ticketsResult.Note,
                ProtectedIdentity =
                    (bool) ticketsResult.Person1ProtectedIdentity
                        ? true
                        : (bool) ticketsResult.Person2ProtectedIdentity ? true : false,
                TicketId = ticketsResult.TicketId.Value,
                Status =
                    EnumUtility.GetEnumDescription((TicketStatusType)
                    Enum.ToObject(typeof(TicketStatusType), ticketsResult.TicketStatusId)),
            };

            if (ticketsResult.OrdinaryBookingDate.HasValue)
            {
                couplesItem.BookingDate = ticketsResult.OrdinaryBookingDate.Value;
                couplesItem.CeremonyType = GetEnumDescription(CeremonyType.Ordinary);
            }

            if (ticketsResult.IndividualBookingDate.HasValue)
            {
                couplesItem.BookingDate = ticketsResult.IndividualBookingDate.Value;
                couplesItem.CeremonyType = GetEnumDescription(CeremonyType.Individual);
            }

            return couplesItem;
        }

        public TicketInformation CreateEntityObject(
            Runtime.Serialization.DataContract.TicketInformation ticketInformation)
        {
            var ticketInfo = new TicketInformation
                       {
                           InformationText = ticketInformation.InformationText,
                           TicketId = ticketInformation.TicketId,
                       };

            return ticketInfo;
        }

        public Runtime.Serialization.DataContract.TicketInformation CreateContractObject(TicketInformation ticketInformation)
        {
            if(ticketInformation == null)
                return null;

            return new Runtime.Serialization.DataContract.TicketInformation
                       {
                           TicketId = ticketInformation.TicketId,
                           InformationText = ticketInformation.InformationText,
                       };
        }

        public Runtime.Serialization.DataContract.History CreateContractObject(History history)
        {
            return new Runtime.Serialization.DataContract.History
                       {
                           HistoryId = history.HistoryId,
                           DateTime = history.ModifiedDate,
                           Information = history.Information,
                           ModifiedByUser = history.ModifiedByUser,
                           TicketId = history.TicketId,
                       };
        }

        private static string GetEnumDescription(Enum enumValue)
        {
            FieldInfo fi = enumValue.GetType().GetField(enumValue.ToString());

            var attributes = (DescriptionAttribute[]) fi.GetCustomAttributes(typeof (DescriptionAttribute), false);

            if (attributes != null && attributes.Length > 0)
                return attributes[0].Description;

            return string.Empty;
        }

        #endregion
    }
}